#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MysqlAdapter.h"

CMysql::CMysql()
: m_mysql_handle(NULL)
, m_query_result(NULL)
, m_isconnected(false)
{
}

CMysql:: ~CMysql()
{
    mysql_free_result(m_query_result);
    m_query_result = NULL;
    Close();
    
}

bool CMysql::Connect(const DbInfo &dbinfo)
{
    if (m_isconnected)
        return false;

    m_mysql_handle = new MYSQL;
    mysql_init(m_mysql_handle);
    if(NULL == m_mysql_handle)
    {
        delete m_mysql_handle;
        return false;
    }

    m_mysql_handle = mysql_real_connect(m_mysql_handle,
              dbinfo.host.c_str(), dbinfo.username.c_str(), 
              dbinfo.passwd.c_str(), NULL, dbinfo.port,
              NULL, 0);

    if(!m_mysql_handle)
    {
        delete m_mysql_handle;
        return false;
    }

    if(mysql_select_db(m_mysql_handle, dbinfo.dbname.c_str()) != 0)
    {
        delete m_mysql_handle;
        return false;		
    }	

    if (!SetNames("utf8"))
    {
        return false;
    }

    m_isconnected = true;
    return true;	
}

bool CMysql::SetNames(const char* pEncode)
{
    if (NULL == m_mysql_handle || NULL == pEncode)
    {
        return false;
    }

    string statement = "SET NAMES ";
    statement += pEncode;
    return (0 == mysql_query(m_mysql_handle, statement.c_str()));
}

void CMysql::Close()
{
    if (!m_isconnected)
        return;

    mysql_close(m_mysql_handle);
    delete m_mysql_handle;
    m_mysql_handle = NULL;	

    m_isconnected = false;
}

bool CMysql::Execute(const char *sql, size_t len)
{	
    if (sql == NULL || !m_isconnected)
        return false;

    FreeResult();

    bool query_success = mysql_real_query(m_mysql_handle, sql, len) == 0;
    if (query_success)
    {
        m_query_result = mysql_store_result(m_mysql_handle);
    }

    return query_success;
}

bool CMysql::FetchRow(vector<string> &row)
{			
    row.clear();
    if(NULL == m_query_result)
        return false;
    
    int ret = false;
    MYSQL_ROW onerow = NULL;
    if ((onerow = mysql_fetch_row(m_query_result)) != NULL)
    {
        int num_fields = mysql_num_fields(m_query_result);
        const unsigned long *len_fields =
                         mysql_fetch_lengths(m_query_result);

        for (int idx_field = 0; idx_field < num_fields; ++idx_field)
        {
            row.push_back(string(onerow[idx_field], len_fields[idx_field]));
        }

        ret = true;
    }

    return ret;		
}

void CMysql::FreeResult(void)
{					
    if (m_query_result != NULL)
    {
        mysql_free_result(m_query_result);
        m_query_result = NULL;
    }
}

string CMysql::EscapeString(const string &src)
{
    //unsigned long mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned long length)
    char *normal_sql = (char*)malloc(src.length() << 1);

    size_t len_normal_sql = mysql_real_escape_string(m_mysql_handle,
                                              normal_sql, src.c_str(), src.length());

    string retstr(normal_sql, len_normal_sql);
    free(normal_sql);
    return retstr;
}

